#include"transfile.h"
bool isExist(const char *filepath,MYSQL* database,char *md5){
    char sql[1024]="select md5 from file where path= ";
    strcat(sql,"'");
    strcat(sql,filepath);
    strcat(sql,"'");
    strcat(sql,"and tomb=0");
    printf("sql=%s\n",sql);    
    int qret=mysql_query(database,sql);
    if(qret!=0){
        printf("error:%s\n",mysql_error(database));
        exit(-1);
    }
    MYSQL_RES* ret=mysql_store_result(database);
    MYSQL_ROW row;
    if((row=mysql_fetch_row(ret))!= NULL){
        strcpy(md5,row[0]);
        printf("服务端文件存在 md5=%s\n",md5);
        return 1;
    }else{
        printf("file is not exist\n");
        return 0;            
    }
}
bool isBigFile(int fd){
    struct stat statbuf;
    fstat(fd,&statbuf);
    if(statbuf.st_size>=BIG_FILE_SIZE){
        printf("big file\n");
        return 1;
    }else{
        printf("small file\n");
        return 0;
    }
}
bool isQuickTrans(const char *filepath,MYSQL* database,char *md5){
     char sql[1024]="select md5 from file where md5 = ";
     strcat(sql,"'");
     strcat(sql,md5);
     strcat(sql,"'");
     int qret=mysql_query(database,sql);
     if(qret!=0){
         printf("error%s\n",mysql_error(database));
         exit(-1);
     }
     MYSQL_RES * res=mysql_store_result(database);
     MYSQL_ROW row;
     if((row=mysql_fetch_row(res))!=NULL){
         strcpy(md5,row[0]);
         printf("秒传\n");
         return 1;
     }
     else{
         printf("不秒传\n");
         return 0;
     }
}
int recvN(int netfd,void* buf,int length){
    int total=0;
    char *p=(char *)buf;
    while(total<length){
        int ret=recv(netfd,p+total,length - total,0);
        if(ret==0){
            return -1;
        }
        total+=ret;
    }
    return 0;
}
int getsFile(int netfd,const char *current_path,const char* filename,MYSQL *database){
    char filepath[1024]={0};
    strcpy(filepath,current_path);
    strcat(filepath,"/");
    strcat(filepath,filename);
    Train train;
    bzero(&train,sizeof(train));
    char md5[1024]={0};
    bool ret=isExist(filepath,database,md5);
    train.length=sizeof(ret);
    memcpy(train.data,&ret,sizeof(ret));
    send(netfd,&train,sizeof(int)+train.length,0);
    if(ret==0){
        printf("服务端文件不存在\n");
        return 0;
    }
    off_t offset;
    int length;
    recvN(netfd,&length,sizeof(int));
    recvN(netfd,&offset,length);
    printf(" offset=%ld\n",offset);
    char true_path[1024]="../san/serc/";
    strcat(true_path,md5);
    printf("true_path=%s\n",true_path);
    int fd=open(true_path,O_RDONLY);
    ret=isBigFile(fd);
    struct stat statbuf;
    fstat(fd,&statbuf);
    bzero(&train,sizeof(train));
    memcpy(train.data, &statbuf.st_size, train.length);
    send(netfd, &train, sizeof(int) + train.length, 0);
    printf(" filesize = %ld\n", statbuf.st_size);
    if(ret==0){
       /* lseek(fd,offset,SEEK_SET);
        while(1){
            bzero(&train,sizeof(train));
            train.length=read(fd,train.data,sizeof(train.data));
            send(netfd,&train,sizeof(int)+train.length,0);
            if(train.length==0){
                break;
            }
        }*/
        sendfile(netfd,fd,NULL,statbuf.st_size);
        printf("send small file over\n");
    }else{
       /* char* p = (char*)mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
        while(offset < statbuf.st_size) {
            bzero(&train, sizeof(train));
            if(sizeof(train.data)<=statbuf.st_size-offset){
                 train.length=sizeof(train.data);
            }else
                train.length=statbuf.st_size-offset;
            memcpy(train.data, p + offset, train.length);
            send(netfd, &train, sizeof(int) + train.length, 0);
            offset += train.length;
          }
         bzero(&train, sizeof(train));
        send(netfd, &train, sizeof(int) + train.length, 0);*/
        sendfile(netfd,fd,NULL,statbuf.st_size);
        printf("提示信息: send big file over\n");
    }
    close(fd);
    return 0;
}
int putsFile(int netfd, const char* current_path, const char* filename, MYSQL* database) {
    int length = 0;
    int client_fd;
    recvN(netfd, &length, sizeof(int));
    recvN(netfd, &client_fd, length);
    if(client_fd == -1) {
        printf("提示信息: 客户端文件不存在\n");
        return 0;
    }

    char filepath[1024] = {0};
    strcpy(filepath, current_path);
    strcat(filepath, "/");
    strcat(filepath, filename);

    Train train;
    bzero(&train, sizeof(train));

    char md5[1024] = {0};
    bool ret = isExist(filepath, database, md5);

    train.length = sizeof(ret);
    memcpy(train.data, &ret, sizeof(ret));
    send(netfd, &train, sizeof(int) + train.length, 0);
    if(ret == 1) {
        printf("提示信息: 服务端文件已存在\n");
        return 0;
    }

    recvN(netfd, &length, sizeof(int));
    printf("提示信息: length = %d\n", length);
    recvN(netfd, md5, length);
    printf("提示信息: md5 = %s\n", md5);

    ret = isQuickTrans(filepath, database, md5);
    train.length = sizeof(ret);
    memcpy(train.data, &ret, sizeof(ret));
    send(netfd, &train, sizeof(int) + train.length, 0);
    if(ret == 0) {
        printf("提示信息: 不秒传\n");
        char true_path[1024] = "../program/";
        strcat(true_path, md5);
        int fd = open(true_path, O_WRONLY | O_CREAT, 0666);
        char buf[1024] = {0};
        while(1)
        {
            recvN(netfd, &length, sizeof(int));
            if(length == 0)
            {
                break;
            }
            bzero(buf, sizeof(buf));
            recvN(netfd, buf, length);
            write(fd, buf, length);
        }
        close(fd);
    }
    else {
        printf("提示信息: 秒传\n");
    }

    char user[255];
    int pre_id;
    char type = 'f';

    char sql[4096] = "SELECT user, id FROM file WHERE path = ";
    strcat(sql, "'");
    strcat(sql, current_path);
    strcat(sql, "'");

    int qret = mysql_query(database, sql);
    if(qret != 0) {
        printf("提示信息: SELECT ERROR: %s\n", mysql_error(database));
        exit(-1);
    }

    MYSQL_RES* res = mysql_store_result(database);
    MYSQL_ROW row;
    if((row = mysql_fetch_row(res)) != NULL) {
        strcpy(user, row[0]);
        pre_id = atoi(row[1]);
    }

    bzero(sql, sizeof(sql));
    sprintf(sql, "INSERT INTO file(filename, type, pre_id, user, path,,tomb, md5) VALUES ('%s', 'f', %d, '%s', '%s',0, '%s')", filename,  pre_id, user,filepath, md5);
    printf("提示信息: sql = %s\n", sql);
    qret = mysql_query(database, sql);
    if(qret != 0) {
        printf("提示信息: INSERT ERROR: %s\n", mysql_error(database));
        exit(-1);
    }

    return 0;
}
